using System;
using System.Collections.Generic;
using System.Text;
using PersistenceObject.Framework.Expressions;
using System.Data;

namespace PersistenceObject.Framework
{
    public class Update : IUpdate, ISqlAccess
    {
        public Update()
        {
        }

        private IDbCommand Command;

        private FieldValue[] fields;
        public FieldValue[] Fields
        {
            get { return fields; }
            set { fields = value; }
        }

        private IDataSession session;
        public IDataSession Session
        {
            get { return session; }
            set { session = value; }
        }

        private Table table;
        public Table Table
        {
            get { return table; }
            set { table = value; }
        }

        private Expression expressions;
        public Expression Expressions
        {
            get { return expressions; }
            set { expressions = value; }
        }

        private IDbCommand CreateCommand()
        {
            IDbCommand comm = this.Session.DbDriver.GetCommand();
            Command = comm;
            StringBuilder sql = new StringBuilder();
            sql.Append("UPDATE ");
            sql.Append(this.Table.Name);
            for (int i = 0; i < this.Fields.Length; i++)
            {
                if (i == 0)
                {
                    if (string.IsNullOrEmpty(this.Fields[i].Sql))
                    {
                        sql.AppendFormat(" SET {0}={1}", this.Fields[i].Name, this.Session.DbDriver.GetParameterName(this.Fields[i].Name));
                    }
                    else
                    {
                        sql.AppendFormat(" SET {0}", this.Fields[i].Sql);
                    }
                }
                else
                {
                    if (string.IsNullOrEmpty(this.Fields[i].Sql))
                    {
                        sql.AppendFormat(",{0}={1}", this.Fields[i].Name, this.Session.DbDriver.GetParameterName(this.Fields[i].Name));
                    }
                    else
                    {
                        sql.AppendFormat(",{0}", this.Fields[i].Sql);
                    }
                }
                if (string.IsNullOrEmpty(this.Fields[i].Sql))
                {
                    comm.Parameters.Add(this.Session.DbDriver.GetParameter(this.Fields[i].Name, this.Fields[i].Value));
                }
            }
            comm.CommandText = sql.ToString();
            CommandBuilder.AddCommandFilter(this.Session.DbDriver, comm, this.expressions);
            DataSession.LastSql = comm.CommandText;
            return comm;
        }

        public int Execute()
        {
            if (this.Table == null)
            {
                //ExceptionError
                throw new Exception("PersistenceObject Error");
            }
            if ((this.Fields == null) || (this.Fields.Length == 0))
            {
                //ExceptionError
                throw new Exception("PersistenceObject Error");
            }
            return this.Session.ExecuteNonQuery(this.CreateCommand());
        }
    }
}
